package com.xuyoupeng.springframework.beans.factory.config;

import com.xuyoupeng.springframework.beans.BeansException;
import com.xuyoupeng.springframework.beans.PropertyValue;
import com.xuyoupeng.springframework.beans.PropertyValues;
import com.xuyoupeng.springframework.beans.core.io.DefaultResourceLoader;
import com.xuyoupeng.springframework.beans.core.io.Resource;
import com.xuyoupeng.springframework.util.StringValueResolver;

import java.util.Properties;

/**
 * @author xuyoupneg
 * @description TODO
 * @date 2024/5/6 11:11
 */
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {

    public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

    public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

    private String location;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            for (String beanName : beanDefinitionNames) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) continue;
                    String strVal = (String) value;
                    StringBuffer stringBuffer = new StringBuffer(strVal);
                    int startIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
                    int stopIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
                    if (startIndex != -1 && stopIndex != -1 && startIndex < stopIndex) {
                        String propKey = strVal.substring(startIndex + 2, stopIndex);
                        String propValue = properties.getProperty(propKey);
                        stringBuffer.replace(startIndex, stopIndex + 1, propValue);
                        propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), stringBuffer.toString()));
                    }
                }
            }

            //向容器中添加注解解析器
            StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties);
            beanFactory.addEmbeddedValueResolver(valueResolver);
        } catch (Exception e) {
            throw new BeansException("Could not  load properties", e);
        }

    }

    private class PlaceholderResolvingStringValueResolver implements StringValueResolver {

        private final Properties properties;

        public PlaceholderResolvingStringValueResolver(Properties properties) {
            this.properties = properties;
        }
        @Override
        public String resolverStringValue(String str) {
            return PropertyPlaceholderConfigurer.this.resolverPlaceholder(str, properties);
        }
    }

    private String resolverPlaceholder(String str, Properties properties) {
        String strVal = str;
        StringBuilder builder = new StringBuilder(strVal);
        int startIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
        int stopIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
        if (startIndex != -1 && stopIndex != -1 && startIndex < stopIndex) {
            String propKey = strVal.substring(startIndex + 2, stopIndex);
            String propertyVal = properties.getProperty(propKey);
            builder.replace(startIndex, stopIndex + 1, propertyVal);
        }
        return builder.toString();
    }

    public void setLocation(String location) {
        this.location = location;
    }
}
